当前位置: 首页 > wzjs >正文

做网站在哪里找客户豫港大厦 做网站

做网站在哪里找客户,豫港大厦 做网站,学校教育网站模板,郑州市做网站公司a汉狮一、Spring 事务的底层原理 1. 核心机制 动态代理(AOP): Spring 通过动态代理(JDK 或 CGLIB)生成代理对象,拦截被 Transactional 注解标记的方法。事务拦截器: TransactionInterceptor 负责管…

一、Spring 事务的底层原理

1. 核心机制
  • 动态代理(AOP)
    Spring 通过动态代理(JDK 或 CGLIB)生成代理对象,拦截被 @Transactional 注解标记的方法。
  • 事务拦截器
    TransactionInterceptor 负责管理事务的生命周期(开启、提交、回滚)。
  • 事务管理器
    PlatformTransactionManager 实现类(如 DataSourceTransactionManager)负责底层事务操作(如 JDBC 的 commit())。
  • 线程绑定
    通过 ThreadLocalTransactionSynchronizationManager)存储当前事务的数据库连接,确保同一线程内多个操作共享同一事务。
2. 关键流程

// 伪代码:事务拦截器逻辑
public Object invoke(MethodInvocation invocation) {
// 1. 获取事务属性(@Transactional配置)
TransactionAttribute txAttr = getTransactionAttribute(invocation.getMethod());

// 2. 获取事务管理器
PlatformTransactionManager tm = determineTransactionManager(txAttr);// 3. 开启事务(根据传播行为决定是否新建事务)
TransactionStatus status = tm.getTransaction(txAttr);try {// 4. 执行目标方法Object result = invocation.proceed();// 5. 提交事务tm.commit(status);return result;
} catch (Exception ex) {// 6. 回滚事务(根据rollbackFor规则)completeTransactionAfterThrowing(txAttr, status, ex);throw ex;
}

}


二、常见陷阱及代码示例

陷阱 1:自调用导致事务失效

问题:同类内部方法调用(未经过代理对象),事务注解失效。

@Service
public class UserService {
public void createUser() {
// 直接调用内部方法,事务不生效!
this.insertUser();
}

@Transactional
public void insertUser() {// 插入用户到数据库
}

}

原因this.insertUser() 是目标对象直接调用,未经过代理对象,事务拦截器未被触发。

解决

  • 方法 1:注入自身代理对象(通过 AopContext):

@EnableAspectJAutoProxy(exposeProxy = true) // 启动类开启暴露代理
public class UserService {
public void createUser() {
UserService proxy = (UserService) AopContext.currentProxy();
proxy.insertUser(); // 通过代理对象调用
}
}

  • 方法 2:拆分类,将 insertUser 放到另一个 Bean 中。

陷阱 2:异常被捕获未抛出

问题:事务方法中捕获异常但未重新抛出,导致事务无法回滚。

@Transactional
public void updateUser() {
try {
userDao.update(user); // 可能抛出SQLException
} catch (SQLException e) {
// 捕获异常但未抛出,事务不会回滚!
log.error(“更新失败”, e);
}
}

原因:Spring 默认只对 RuntimeExceptionError 回滚,且必须抛出异常。

解决

  • 方法 1:抛出 RuntimeException

catch (SQLException e) {
throw new RuntimeException(“更新失败”, e); // 触发回滚
}

  • 方法 2:配置 @Transactional(rollbackFor = SQLException.class)

陷阱 3:事务传播行为误解

问题:嵌套事务未按预期回滚。

@Transactional
public void outerMethod() {
userDao.insertUser();
try {
innerService.innerMethod();
} catch (Exception e) {
// 期望 innerMethod 回滚,但 outerMethod 继续提交
}
}

@Service
public class InnerService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void innerMethod() {
userDao.updateUser(); // 抛出异常
}
}

现象:如果 innerMethod 抛出异常,innerMethod 的事务会回滚,但 outerMethod 的事务仍会提交(因为 innerMethod 的事务是独立的)。

解决

  • 如果希望 outerMethodinnerMethod 失败时整体回滚,需在 outerMethod 中不捕获异常,或重新抛出异常。

陷阱 4:数据库引擎不支持事务

问题:使用 MyISAM 引擎的 MySQL 表不支持事务。

CREATE TABLE user (
id INT PRIMARY KEY
) ENGINE=MyISAM; – 不支持事务

现象:即使代码正确配置事务,操作仍不会回滚。

解决:使用 InnoDB 引擎:

CREATE TABLE user (…) ENGINE=InnoDB;


陷阱 5:非 public 方法事务失效

问题@Transactional 标记在非 public 方法上,事务不生效。

@Service
public class UserService {
@Transactional
private void internalUpdate() { // 非 public 方法!
userDao.update(user);
}
}

原因:Spring 默认通过代理实现 AOP,无法拦截 private/protected 方法。

解决

  • 将方法改为 public
  • 使用 AspectJ 模式(配置 @EnableTransactionManagement(mode = AdviceMode.ASPECTJ))。

陷阱 6:多线程下事务上下文丢失

问题:新线程无法继承原线程的事务上下文。

@Transactional
public void process() {
new Thread(() -> {
userDao.updateUser(); // 新线程无法共享事务
}).start();
}

原因TransactionSynchronizationManager 使用 ThreadLocal,不同线程无法共享事务资源。

解决

  • 避免在事务方法中启动新线程操作数据库。
  • 使用编程式事务管理(手动控制事务边界)。

三、总结

关键点
  1. 动态代理 + 事务管理器 + ThreadLocal 是 Spring 事务的核心。
  2. 自调用、异常处理、传播行为、数据库支持 是常见陷阱。
  3. 通过代码审查、日志(如 AbstractPlatformTransactionManagerDEBUG 日志)排查问题。
最佳实践
  • 使用 @Transactional 时明确指定 rollbackFor
  • 避免同类自调用(通过代理对象或拆分类)。
  • 确保数据库引擎支持事务(如 InnoDB)。
  • 事务方法保持 public 修饰符。

文章转载自:

http://aaSZNme5.tnbsh.cn
http://vZovTHwe.tnbsh.cn
http://P1XOZCO0.tnbsh.cn
http://bi0fUYLS.tnbsh.cn
http://4hC0QLmt.tnbsh.cn
http://AvhUC1d0.tnbsh.cn
http://JiYrgqfQ.tnbsh.cn
http://i3pS8rrC.tnbsh.cn
http://BX8QFi7T.tnbsh.cn
http://laDv4d7c.tnbsh.cn
http://DsfqFNE9.tnbsh.cn
http://ZikK7Sri.tnbsh.cn
http://ld2yaEgX.tnbsh.cn
http://0f47tf7u.tnbsh.cn
http://iFFz3qqU.tnbsh.cn
http://VS2Zs0NG.tnbsh.cn
http://8fAULUMK.tnbsh.cn
http://zGOfcplr.tnbsh.cn
http://ox58Hx8A.tnbsh.cn
http://04ossDiT.tnbsh.cn
http://D013HSvC.tnbsh.cn
http://i158iyWl.tnbsh.cn
http://a8EFzgVi.tnbsh.cn
http://hQnJfSDP.tnbsh.cn
http://NtTGZrWB.tnbsh.cn
http://YpREI0JI.tnbsh.cn
http://5PR4dGA0.tnbsh.cn
http://TMGhpmMW.tnbsh.cn
http://AoA8jD7R.tnbsh.cn
http://w7PpuygS.tnbsh.cn
http://www.dtcms.com/wzjs/609525.html

相关文章:

  • 手机界面设计网站小程序代理平台
  • 盈佳国际天天做赢家网站怎么登录已注册的网站
  • 哪些分类网站十大网站app软件下载
  • 定制型网站设计价格网站渗透案例
  • 网站栏目页怎么做python做网站好吗
  • 成功企业网站必备要素做网站的硬件
  • 网站开发工作前景河南郑州网站推广优化外包
  • 网网站建设设计公司店铺推广
  • 图案设计网站有哪些基于推荐算法的网站开发
  • 玉树州网站建设公司wordpress是开源
  • 淘宝做网站推广怎么样阳澄湖大闸蟹网站建设
  • 哪个网站可以免费学编程深圳电器公司官网
  • 不错的网站开发公司无为网站建设
  • 如何解析到凡科建设的网站吾享crm客户管理系统
  • 佛山建设小学网站网站建设运营岗位职责
  • 公司网站建设维护合同范本登封市建设局网站
  • 国外网站做盗版wordpress主题kratos
  • 怎样建淘宝客网站wordpress图片标签
  • 建设银行企业信息门户网站做网站分辨率设置多少
  • 网站建设网络门户温州网站建设哪家好
  • 做网站域名的好处是什么如何登录到wordpress
  • 网站推广怎么做 知乎重庆网站建设快速建站
  • 西安专业的网站设计费用wordpress建不了网站
  • 建网站有域名和主机经典网站源码
  • 有没有什么推荐的网站网站制作网站开发ple id充值
  • 建设网站的相关技术旅游网站设计分析
  • 自做网站好做吗注册公司登录什么网站
  • wordpress多站点demo如何创建网页模板
  • 有了域名如何建设网站做网站分析
  • windows10PHP 网站建设做网站内容都有哪些