Spring事务配置隔离级别Isolation.READ_COMMITTED引发的一系列问题


这两天改了下spring事务隔离级别,使用Isolation.READ_COMMITTED,导致了放到生产环境马上出现错误。这是在测试环境没有的,找log发现了:

Caused by: java.sql.SQLException: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.
本着好记性不如烂笔头的想法,记录下解决这个bug中间学习到的新东西吧。
基本原因就是mysql记录数据库操作日志的这种 BINLOG_FORMAT = STATEMENT方式,不支持这种READ COMMITTED or READ UNCOMMITTED事务级别。

解决方案:binlog_format=row,这行添加在my.cnf里面的[mysqld]下面,重启mysql服务就行。如果是主从的话就要两个库都配置这样。这到底是为什么呢,我这种小白也不懂,都是google来的。

由于生产是主从库,不敢随便在生产弄,测试没主从,就配一波mysql主从配置。

很大程度上参考这里:https://blog.csdn.net/xlgen157387/article/details/51331244

先配置下主库:

my.cnf里面[mysqld]下面添加

#master slave
log-bin=mysql-bin	//这个应该是记录操作日志的吧(不是特别理解)
server-id=93		//这个我理解为是整个服务器的id,我直接放服务器最后一个ip段
binlog-ignore-db=information_schema	
binlog-ignore-db=cluster
binlog-ignore-db=mysql
#上面三个是忽略操作
binlog-do-db=capki0714 //这个是你需要操作的数据库
#记录日志格式
binlog_format=row
配置从库:

my.cnf里面[mysqld]下面添加

log-bin=mysql-bin
server-id=131
binlog-ignore-db=information_schema
binlog-ignore-db=cluster
binlog-ignore-db=mysql
replicate-do-db=capki0714
replicate-ignore-db=mysql
log-slave-updates	//此参数网上查是说可以用来记录日志,将从库做主库。(应该是做成多级从库的形式)
slave-skip-errors=all
slave-net-timeout=60
#记录日志格式
binlog_format=row
主从的配置文件都修改完毕了。
再次回到主库运行:
show master status;

将里面显示的数据记录出来

change master to master_host='192.168.162.93',master_user='root',master_password='yourpasswd',master_log_file='mysql-bin.000003', master_log_pos=9326;
	
master_host=主库ip,master_user=主库用户,master_password=用户密码,master_log_file=对应status信息的File, master_log_pos=对应status信息的Position
记录完毕。
回到从库:

执行刚刚那个条记录,

change master to master_host='192.168.162.93',master_user='root',master_password='yourpasswd',master_log_file='mysql-bin.000003', master_log_pos=9326;
start slave;
show slave status \G;

启动从库复制操作。看信息是否正确,然后在主库添加记录看看是否成功了。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring中,事务隔离级别由`Isolation`枚举类定义,其中包括以下五个级别: - DEFAULT:使用底层数据库默认的隔离级别。 - READ_UNCOMMITTED:允许读取未提交的数据更改。可能导致脏读、幻读或不可重复读。 - READ_COMMITTED:只允许读取已经提交的数据。可以避免脏读,但可能会有幻读或不可重复读。 - REPEATABLE_READ:确保在同一事务中多次读取相同的数据时,每次读取的数据都是一致的。可以避免脏读和不可重复读,但仍可能会出现幻读。 - SERIALIZABLE:确保在同一事务中多次读取相同的数据时,每次读取的数据都是一致的,并且可以避免脏读、不可重复读和幻读。 下面是一个使用`Isolation.READ_COMMITTED`隔离级别的示例代码: ```java @Service public class UserServiceImpl implements UserService { private final UserRepository userRepository; public UserServiceImpl(UserRepository userRepository) { this.userRepository = userRepository; } @Transactional(isolation = Isolation.READ_COMMITTED) @Override public User updateUserNickname(Long userId, String nickname) { User user = userRepository.findById(userId).orElseThrow(() -> new RuntimeException("User not found")); user.setNickname(nickname); userRepository.save(user); return user; } } ``` 在上面的代码中,`@Transactional`注解指定了使用`Isolation.READ_COMMITTED`隔离级别。当调用`updateUserNickname`方法时,Spring会在事务中执行该方法的所有数据库操作,并将它们隔离到其他事务之外,以确保数据的一致性和可靠性。此外,如果在事务中发生任何错误,Spring会自动回滚该事务中的所有操作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值