spring 事务实现方式有哪些?

spring 事务实现方式有哪些?

 

事务的使用场景

一个用户操作下包含多个数据库修改操作(增、删、改)时, 必须确保这些修改操作要么同时执行,要么同时不执行, 那么这个用户操作涉及到的代码块必须要加事务。

spring 事务实现方式

  1. 编程式事务管理(对基于 POJO 的应用来说是唯一选择) 我们需要在代码中调用beginTransaction()、commit()、rollback()等事务管理相关的方法

  2. 声明式事务

    基于 TransactionProxyFactoryBean的声明式事务管理

    基于 注解@Transactional 的声明式事务管理

    基于 Aspectj AOP 配置(注解)事务

 

  1. 编程式事务管理

    在Spring中,编程式事务管理可以通过TransactionTemplate或者PlatformTransactionManager接口来实现。

    • 使用TransactionTemplateTransactionTemplate是一个模板类,提供了一种回调机制,允许你在一个事务中执行多个操作。

        @Autowired
        private TransactionTemplate transactionTemplate;
    ​
        @Autowired
        public MyService(PlatformTransactionManager transactionManager, MyRepository myRepository) {
            this.transactionTemplate = new TransactionTemplate(transactionManager);
            this.myRepository = myRepository;
    ​
            // 定制事务属性
            this.transactionTemplate.setPropagationBehavior(Propagation.REQUIRES_NEW.value());
            this.transactionTemplate.setIsolationLevel(Isolation.DEFAULT.value());
            this.transactionTemplate.setTimeout(30); // 设置超时时间,单位为秒
        }
    ​
        // 编程式事务管理实现
        public void createEntityByTemplate(MyEntity myEntity) {
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(TransactionStatus status) {
                    myRepository.save(myEntity);
                }
            });
        }
    ​

     

    • 使用PlatformTransactionManager:这个接口提供了更低层次的事务控制,允许你显式地开始、提交和回滚事务。

          @Autowired
          private PlatformTransactionManager transactionManager;
      ​
          public void createEntityByTransactionManager(MyEntity myEntity) {
              TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
              try {
                  myRepository.save(myEntity);
                  transactionManager.commit(status);
              } catch (DataAccessException e) {
                  transactionManager.rollback(status);
                  throw e;
              }
          }
      ​

       

     

    我们需要在代码中调用beginTransaction()、commit()、rollback()等事务管理相关的方法

     

    package constxiong.interview.transaction;
     
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
     
    import javax.sql.DataSource;
     
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
     
    public class TransactionTest {
     
        public static void main(String[] args) throws Exception {
            testManualTransaction();//测试函数式控制事务
        }
        
        private static void testManualTransaction() throws SQLException {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring_transaction.xml");
            DataSource ds = (DataSource)context.getBean("datasource");
            Connection conn = ds.getConnection();
            try {
                initTable(conn);//初始化表
                conn.setAutoCommit(false);//设置不自动提交事务
                queryUsers(conn);//查询打印用户表
                deleteUser(conn);//删除 id=1 用户
                conn.rollback();//回滚
                queryUsers(conn);//查询打印用户表
            } finally {
                conn.close();
            }
        }
     
        private static void initTable(Connection conn) throws SQLException {
            conn.createStatement().execute("drop table if exists user");
            conn.createStatement().execute("create table user(id int, username varchar(60)) ENGINE=InnoDB DEFAULT CHARSET=utf8 ");//是否支持事务与数据库引擎有关,此处删除 ENGINE=InnoDB DEFAULT CHARSET=utf8 可能不支持事务
            conn.createStatement().execute("insert into user values(1, 'user1')");
            conn.createStatement().execute("insert into user values(2, 'user2')");
        }
     
        private static void deleteUser(Connection conn) throws SQLException {
            conn.createStatement().execute("delete from user where id = 1");
        }
     
        private static void queryUsers(Connection conn) throws SQLException {
            Statement st = conn.createStatement();
            st.execute("select * from user");
            ResultSet rs = st.getResultSet();
            while (rs.next()) {
                System.out.print(rs.getString("id"));
                System.out.print(" ");
                System.out.print(rs.getString("username"));
                System.out.println();
            }
        }
        
    }

    手动事务管理可以在用JDBC操作数据库时使用。

  2. 基于 TransactionProxyFactoryBean的声明式事务管理

    修改 spring 配置文件,添加事务管理器 DataSourceTransactionManager 和事务代理类 TransactionProxyFactoryBean

    测试代码:

    package constxiong.interview.transaction;
     
    import java.util.Map;
     
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
     
    public class TransactionTest {
     
        static ApplicationContext context = new ClassPathXmlApplicationContext("spring_transaction.xml");
        
        public static void main(String[] args) throws Exception {
            testUseTransactionProxy(); //测试使用 spring TransactionProxyFactoryBean
        }
        
        private static void testUseTransactionProxy() {
            final UserDao userDao = (UserDao)context.getBean("userProxy");
            printUsers(userDao);//打印用户
            userDao.deleteUser(1);//删除 id=1 用户
        }
     
        private static void printUsers(UserDao userDao) {
            for (Map<String, Object> user : userDao.getUsers()) {
                System.out.println(user);
            }
        }
     
    }

     

  3. 基于 注解@Transactional 的声明式事务管理

    这种方式比较简单,被注解@Transactional声明的方法内,只要有一个数据库修改操作出现异常,之前执行过的修改操作也会回滚。

    测试代码:

    package constxiong.interview.transaction;
     
    import java.util.Map;
     
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
     
    public class TransactionTest {
     
        static ApplicationContext context = new ClassPathXmlApplicationContext("spring_transaction.xml");
        
        public static void main(String[] args) throws Exception {
            testAnnotationTransaction();
        }
        
        
        private static void testAnnotationTransaction() {
            UserDao userDao = (UserDao)context.getBean("userDao");
            printUsers(userDao);
            userDao.deleteUser(1);
        }
     
     
        private static void printUsers(UserDao userDao) {
            for (Map<String, Object> user : userDao.getUsers()) {
                System.out.println(user);
            }
        }
     
    }

     

  4. 基于 Aspectj AOP 配置(注解)事务

     

    参考:spring 事务实现方式有哪些?-优快云博客

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值