数据库——并发事务问题

一、事务的四大特性

1、原子性:事务中的所有操作都是不可分割的原子单位。事务中的所有操作要么全部执行成功,要么全部执行失败。
2、一致性:事务执行后,数据库状态与其他与其他业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
3、隔离性:隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
4、持久性:一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。

二、并发事务中出现的问题

1、脏读(dirty read):一个事务读取到另外一个事务中未提交的更新数据,即读取到了脏数据;
2、不可重复读(unrepeatable read):对同一记录的两次读取不一致,因为另一事务对该记录做了修改;
3、幻读(phantom read):又称虚读,事务在两次查询返回的数据中发生了数据的缺少或增加,因为另一事务插入或删除了一条记录。

不可重复读与幻读的区别在于,不可重复读是针对同一条记录,在相同的条件下,发现这条记录发生了更改,而幻读则是事务在插入已经检查过不存在的记录时,惊奇的发现这些数据已经存在了,之前的检测获取到的数据如同鬼影一般。

三、四大隔离级别

4个等级的隔离级别,在相同的数据环境下,使用相同的输入,执行相同的工作,根据不同的隔离级别,可以导致不同的结果。不同事务隔离级别能够解决的数据并发问题是不一样的。

1、SERIALIZABLE(串行化)

  • 不会出现任何问题,因为它是对同一数据的访问时串行的,非并发访问!
  • 性能最差!

2、REPEATABLE READ(可重复读)

  • 防止脏读和不可重复读,不能处理幻读问题!
  • 性能较SERIALIZABLE好。

3、READ COMMITTED(读已提交数据)

  • 防止脏读,没有处理不可重复读和幻读;
  • 性能较前两种更佳。

4、READ UNCOMMITTED(读未提交数据)

  • 可能出现上述所有的事务并发问题;
  • 性能在四种隔离中最优!

MySQL的默认隔离级别为REPEATABLE READ!

四、设置隔离级别:
1、MySQL的默认隔离级别为REPEATEBLE READ,可以使用下面语句查看:

select @@tx isolation

也可以通过下面语句来设置当前连接的隔离级别:

set transaction isolationlevel[四选一]

2、JDBC设置隔离级别

connection.setTransactionIsolation(int level);
"参数可选值如下:"
Connection.TRANSACTION_READ_UNCOMMITTED;
Connection.TRANSACTION_READ_COMMITTED;
Connection.TRANSACTION_REPEATABLE_READ;
Connection.TRANSACTION_SERIALIZABLE。

你可能感兴趣的