赞
踩
@Transactional注解是Spring框架中用于声明式事务管理的关键注解。本文将深入探讨@Transactional注解的作用、使用方式和常见属性,并结合代码实例演示其在实际项目中的应用,以帮助读者更好地理解和使用该注解。
@Transactional注解是Spring框架提供的一个用于声明式事务管理的注解。它可以应用在方法或类上,用于标识需要进行事务管理的方法或类。通过使用@Transactional注解,我们可以更加方便地管理事务,保障数据的一致性和可靠性。在介绍@Transactional注解之前,我们先来了解一下事务的基本概念。事务具有四个基本特性:「原子性 」、「一致性 」、「隔离性 」和「持久性 」。
使用@Transactional注解的方式 @Transactional注解可以应用在方法或类上。
public class TransactionalAnnotationProcessor { private PlatformTransactionManager transactionManager; public TransactionalAnnotationProcessor(PlatformTransactionManager transactionManager) { this.transactionManager = transactionManager; } public Object process(Object target, Method method, Object[] args) throws Throwable { Transactional transactional = method.getAnnotation(Transactional.class); TransactionStatus transactionStatus = null; try { // 开启事务 transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition()); // 执行目标方法 Object result = method.invoke(target, args); // 提交事务 transactionManager.commit(transactionStatus); return result; } catch (Exception ex) { // 回滚事务 if (transactionStatus != null) { transactionManager.rollback(transactionStatus); } throw ex; } } }
TransactionalAnnotationProcessor类是一个简化版本的注解解析器。它接收一个PlatformTransactionManager对象作为构造函数的参数,用于管理事务。process()方法接收目标对象、目标方法和方法参数作为参数。该方法首先通过反射获取目标方法上的@Transactional注解,然后根据注解的配置开启事务。接着,执行目标方法,并根据方法执行的结果决定是提交事务还是回滚事务。
@Transactional(rollbackFor = Exception.class) private void executeInsertSQL(String tableName,String columnName,String placeholderOfColumnName,List<String> fieldNameList,List<Object> valuesOfField ) throws SQLException { TransactionStatus transactionStatus=null; PlatformTransactionManager transactionManager=null; try{ String sql = "insert into "+tableName+" (" + columnName + ") values(" + placeholderOfColumnName + ")"; //获取EntityManager对象 EntityManager entityManager = Actor.applicationContext.getBean(EntityManager.class); transactionManager = Actor.applicationContext.getBean(PlatformTransactionManager.class); //手动开启事务 transactionStatus= transactionManager.getTransaction(new DefaultTransactionDefinition()); // 使用EntityManager执行JPA操作 Query nativeQuery = entityManager.createNativeQuery(sql); for (int i=0;i<valuesOfField.size();i++){ nativeQuery.setParameter(fieldNameList.get(i), valuesOfField.get(i)); } nativeQuery.executeUpdate(); //手动提交事务 transactionManager.commit(transactionStatus); }catch (Exception e){ if(transactionStatus!=null ){ //回滚事务 transactionManager.rollback(transactionStatus); } e.printStackTrace(); } }
Transactional注解标注方法修饰符为非public时,@Transactional注解将会不起作用。因此在方法抛出异常时,nativeQuery.executeUpdate();操作不会进行回滚。如果executeInsertSQL方法改为public的话将会正常开启事务,然后在决定是提交事务还是回滚。
public void text() throws SQLException { List<Object> objects = new ArrayList<>(); List<String> stringList = new ArrayList<>(); this.executeInsertSQL("12","21","wzl",stringList,objects); } /* * @description:执行插入的sql语句 * @author: wuzilong * @date: 2023/6/12 17:10 * @param: [tableName, fieldStr, valueStr, fieldNameList, values] * @return: void **/ @Transactional(rollbackFor = Exception.class) public void executeInsertSQL(String tableName,String columnName,String placeholderOfColumnName,List<String> fieldNameList,List<Object> valuesOfField ) throws SQLException { TransactionStatus transactionStatus=null; PlatformTransactionManager transactionManager=null; try{ String sql = "insert into "+tableName+" (" + columnName + ") values(" + placeholderOfColumnName + ")"; //获取EntityManager对象 EntityManager entityManager = Actor.applicationContext.getBean(EntityManager.class); transactionManager = Actor.applicationContext.getBean(PlatformTransactionManager.class); //手动开启事务 transactionStatus= transactionManager.getTransaction(new DefaultTransactionDefinition()); // 使用EntityManager执行JPA操作 Query nativeQuery = entityManager.createNativeQuery(sql); for (int i=0;i<valuesOfField.size();i++){ nativeQuery.setParameter(fieldNameList.get(i), valuesOfField.get(i)); } nativeQuery.executeUpdate(); //手动提交事务 transactionManager.commit(transactionStatus); }catch (Exception e){ if(transactionStatus!=null ){ //回滚事务 transactionManager.rollback(transactionStatus); } e.printStackTrace(); } }
调用一个方法在类内部调用内部被@Transactional标注的事务方法,运行结果是事务不会正常开启,nativeQuery.executeUpdate();操作将会保存到数据库不会进行回滚。
@Transactional(rollbackFor = Exception.class) public void executeInsertSQL(String tableName,String columnName,String placeholderOfColumnName,List<String> fieldNameList,List<Object> valuesOfField ) throws SQLException { TransactionStatus transactionStatus=null; PlatformTransactionManager transactionManager=null; try{ String sql = "insert into "+tableName+" (" + columnName + ") values(" + placeholderOfColumnName + ")"; //获取EntityManager对象 EntityManager entityManager = Actor.applicationContext.getBean(EntityManager.class); transactionManager = Actor.applicationContext.getBean(PlatformTransactionManager.class); //手动开启事务 transactionStatus= transactionManager.getTransaction(new DefaultTransactionDefinition()); // 使用EntityManager执行JPA操作 Query nativeQuery = entityManager.createNativeQuery(sql); for (int i=0;i<valuesOfField.size();i++){ nativeQuery.setParameter(fieldNameList.get(i), valuesOfField.get(i)); } nativeQuery.executeUpdate(); //手动提交事务 transactionManager.commit(transactionStatus); }catch (Exception e){ System.out.println("抛出了一个异常"); } }
运行程序发现,虽然抛出异常,但是异常被捕捉了,没有抛出到方法外, nativeQuery.executeUpdate();操作并没有回滚。
//⾃定义的异常可以进⾏回滚
@Transactional( propagation = Propagation .REQUIRED , rollbackFor = MyException . class
//所有的异常可以进⾏回滚
@Transactional(rollbackFor = Exception.class)
以上是一些常用的与@Transactional注解相似的注解,它们都可以用来简化开发、提高代码的可读性和可维护性。您可以根据实际需求选择合适的注解来使用。
@Transactional注解是Spring框架中用于声明式事务管理的关键注解。通过使用@Transactional注解,我们可以更加方便地管理事务,保障数据的一致性和可靠性。在实际项目中,合理使用@Transactional注解可以提高「开发效率 」和代码「可维护性 」。希望本文能帮助读者更好地理解和使用@Transactional注解。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。