代码大概如下:
@Service
public class UserServiceImpl implements UserService {
@Transactional
public void insertA() throws Exception {
roleDao.insert(role); //在角色表插入数据
insertB();
}
@Transactional
public int insertB() throws Exception {
userDao.insert(user); //在用户表插入的数据有重复主键
}
}
A 方法用 roleDao 在角色表插入数据,然后调用 B 方法。
B 方法里面,用 userDao 插入用户表的数据存在重复主键。
两个方法都加了 @Transactional,B 方法在插入用户表时肯定不会成功,
那么事务会回滚,A 方法中的插入角色表应该也会回滚才对吧??
但是不知道为什么每次 A 方法的角色表的数据还是成功插入了。。
1
751327 2020-09-01 19:05:09 +08:00
insertA 这个方法是 UserServiceImpl 里面的方法调用吗
|
2
skypyb 2020-09-01 19:17:26 +08:00
这里 UserServiceImpl 实际上是在调用"自己"的方法, 而不是 Spring 代理的类的方法。
|
3
javaWeber OP @751327 insertA 这个方法是 UserServiceImpl 里面的方法调用吗
========================================== insertA ()只在控制层调用了。 |
4
mahogany 2020-09-01 19:18:12 +08:00
嵌套事务?
|
5
skypyb 2020-09-01 19:19:45 +08:00
上边说有点不对。 你 A 既然加了事务,那 B 加不加都无所谓了。 是不是抛的异常不是运行时异常啊 = =
|
6
javaWeber OP @skypyb 上边说有点不对。 你 A 既然加了事务,那 B 加不加都无所谓了。 是不是抛的异常不是运行时异常啊
============================================================= 这里后台报错提示的异常是 DuplicateKeyException,这个异常也是 RuntimeException 的子类。。 dao 层那边是直接在方法后面 throws Exception 。。这个有影响么? |
7
skypyb 2020-09-01 19:45:26 +08:00
@javaWeber #6 Spring 只处理运行时异常, 受检异常无视的。 如果抛出的是受检异常是就可能出现改了不回滚的情况。
|
8
qgs 2020-09-01 19:59:25 +08:00
|
9
aitaii 2020-09-01 21:28:16 +08:00
建议了解一下 spring 是如何开启事务的,这样就明白为什么没有起作用了。
关键词 spring 事务 原理 aop 动态代理 |
10
javaWeber OP 怀疑是自调用,或者非运行时异常导致的。
我直接写到一个方法里面,抛的异常也改成了运行时异常。 用户表插入重复主键的数据,插入失败。 而在同一个方法里面,在角色表插入数据,最后却插入成功了。。 事务还是没有回滚啊。好奇怪。。 如下所示: ``` @Service public class UserServiceImpl implements UserService { @Transactional public void insertA() throws RuntimeException { roleDao.insert(role); //在角色表插入数据 userDao.insert(user); //在用户表插入的数据有重复主键 } } ``` |
11
AmosAlbert 2020-09-01 23:31:26 +08:00
insertB()没有被增强
|
12
10Buns 2020-09-01 23:51:31 +08:00
自调用时,并不是调用代理累的方法,自然 Spring 事务不会生效了
|
13
wakzz 2020-09-02 00:18:49 +08:00
因为是内部直接调用,没有走代理,所以基于代理的事务就不生效了
|
14
Xbluer 2020-09-02 04:22:07 +08:00 via iPhone
也许只是 auto commit 了
|
15
xuanbg 2020-09-02 07:17:47 +08:00
同一个类里面的不行,insertB 放到 roleDao 类里面就好。
@Service public class UserServiceImpl implements UserService { @Transactional public void insertA() throws Exception { roleDao.insert(role); //在角色表插入数据 roleDao.insertB(); } } |
16
wellR 2020-09-02 08:46:02 +08:00 via Android
调用 b 时,没有走 aop,应该在此 service 中注入自身,用这个注入的实例去调用 b
|
17
pierswu 2020-09-02 08:48:47 +08:00
你在 insertA 设置里面设置一个断点,看看调用堆栈里面有没有事务的 aop,我怀疑你的事务根本没生效
|
18
dbkx 2020-09-02 10:27:32 +08:00
事实上,如果使用 @Transaction 方法里嵌套调用的是同一个类的方法,spring 代理会忽略嵌套方法的 @Transaction 配置。但是,如果是其他注入对象的方法,那么 @Transaction 配置就会生效。
|
19
dengjunwen 2020-09-02 11:10:25 +08:00 via Android
@xuanbg 看下你的调用代码。现在 问题应该出现在调用部分和 transaction 配置部分
|
20
Habyss 2020-09-02 14:36:40 +08:00
楼主代码是 `同类中事务方法调用事务方法, 不会出现事务失效问题, 但是却会出现事务传播失效问题`
多问一句, 你这个项目有用 shiro 之类的权限管理吗? 如果用了的话, 有在相关权限配置类里面注入这个 Service 类吗? |