因为 项目开发,有第三方的回调。。。可能须要用到 多线程,因此 测试了一下 spring的多线程事务。html
new Thread(new Runnable() { @Override public void run() { System.out.println("22>>"); boscRequestLogService.test(); } }).start(); 通过测试, 若是 在 boscRequestLogService.test() 方法里面 ,产生了异常,是能够回滚的。 也就是说, 新线程,在 boscRequestLogService.test() 方法里面的 全部调的方法 都是 对应 spring 声明事务都是能够起做用的,和 controller 没有关系。
public void test() { System.out.println("33>>"); BoscRequestLog log = this.getByRequestNo("20171221100422"); log.setReturnErrorMsg("test8888"); this.update(log); System.out.println("44>>"); int a = 1; if (a == 2) { System.out.println("55>>"); throw new NullPointerException("我是空"); } test2(); } public void test2() { new Thread(new Runnable() { @Override public void run() { // 自定义事务控制,达到 以后的业务出现了异常这个充值里面的记录不会回滚 DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。 TransactionStatus status = transactionManager.getTransaction(def); // 得到事务状态 try { System.out.println("66>>"); BoscRequestLog log = getByRequestNo("20171221100646"); log.setReturnErrorMsg("000"); update(log); int a = 1; if (a == 1) { System.out.println("77>>"); throw new NullPointerException("我是空"); } transactionManager.commit(status); // 提交事务 } catch (Exception e) { // TODO Auto-generated catch block // e.printStackTrace(); System.out.println("...回滚"); transactionManager.rollback(status); // 回滚事务 throw new NullPointerException("我是空"); } } }).start(); }
对应 在 service 层里面 创建 多线程执行 方法,那么 声明事务就不会起做用了,出现异常不会回滚的。 因此就须要再 多线程里面 本身控制事务了 因此使用了 DefaultTransactionDefinition def = new DefaultTransactionDefinition(); 。。。spring
这样在 多线程里面 产生了异常, 多线程里面的方法是能够回滚事务的安全
不过有一个特殊状况就是 。 好比 上面 test2 方法产生了 异常,抛出去了,在 test 方法 并不能 回滚事务。 也就是 多线程来讲, 对于 以前 执行的方法,是不能回滚事务的。声明事务没有做用。 除非 test 方法 本身 定义一个事务控制, try-catch test2 方法,有异常就 回滚就能够。多线程
// spring没法处理thread的事务,声明式事务无效ide