事务

事务(Transaction)

	指一组操作,里面包含许多个单一的逻辑,只要有一个逻辑没有执行成功,那么都算失败,所有的数据回归到最初的状态(回滚)
  • 事务用处
    为了确保逻辑的成功。例:银行转账

使用代码方式演示事务

代码里的事务只要是针对链接

  • 步骤:
  1. 通过conn.setAutoCommit(false)来关闭自动提交的设置
  2. 提交事务conn.commit()
  3. 回滚事务 conn.rollback()

事务的特性ACID

  • 原子性
    事务中包含的逻辑不可分割
  • 一致性
    事务执行前后数据完整
  • 隔离性
    事务在执行期间不应该受到其他事务的影响
  • 持久性
    事务执行成功后数据应该持久保存在磁盘上

事务的安全隐患

隔离级别

  • Read Uncommitted【读未提交】
    一个事务可以读取到另一个事务还未提交的数据,会引发“脏读”,读取到的是数据库内存中的数据,而并非真正磁盘上的数据
    引发:脏读

  • read Committed【读已提交】
    只能读取到其他事务已经提交的数据,那些没有提交的数据是读不出来的,但是这回造成一个问题是:前后读取到的结果不一样,发生了不可重复。所谓的不可重复,就是不能执行多次读取,否则出现结果不一
    解决:脏读,引发:不可重复读

  • Repeatable Read【重复读】
    MySQL默认的隔离级别
    可以让事务在自己的会话中重复读取数据,并且不会出现结果不一样的状况,即使其他事务已经提交了,也依然还是显示以前的数据
    解决:不可重复读和脏读 没有解决:幻读

  • Serializable【可串行化】
    最高级事务级别,可解决之前三个问题,但效率较低,比较少用
    如果有一个连接的隔离级别设置为了串行化,那么谁先打开了事务,谁就有了先执行的权利,谁后打开事务,只能等着前面那个事务提交或者回滚,才能执行

    mysql:默认隔离级别:可重复读
    oracle:默认隔离级别:读已提交

    效率划分:
    读未提交 > 读已提交 > 可重复度读 > 可串行化
    按拦截程度:
    可串行化 > 可重复读 > 读已提交 > 读未提交

不考虑隔离级别设置,会出现以下问题

  1. 脏读
    一个事务读到另外一个事务还未提交的数据
  2. 不可重复读
    前后多次读取,数据内容不一致。读取了其他事务更改的数据,针对update操作
  3. 幻读
    前后多次读取,数据总量不一致。读取了其他事务新增的数据,针对insert操作

丢失数据

  1. 如果不考虑隔离性,也会产生写入数据的问题,这一类的问题叫丢失更新的问题。
  2. 例如:两个事务同时对某一条记录做修改,就会引发丢失更新的问题。
  • A事务和B事务同时获取到一条数据,同时再做修改
  • 如果A事务修改完成后,提交了事务
  • B事务修改完成后,不管是提交还是回滚,如果不做处理,都会对数据产生影响
  1. 解决方案有两种
  • 悲观锁

    • 采用的是数据库提供的一种锁机制,如果采用做了这种机制,在SQL语句的后面添加 for update 子句
    • 当A事务在操作该条记录时,会把该条记录锁起来,其他事务是不能操作这条记录的。
    • 只有当A事务提交后,锁释放了,其他事务才能操作该条记录
  • 乐观锁

    • 采用版本号的机制来解决的。会给表结构添加一个字段version=0,默认值是0
    • 当A事务在操作完该条记录,提交事务时,会先检查版本号,如果发生版本号的值相同时,才可以提交事务。同时会更新版本号version=1.
    • 当B事务操作完该条记录时,提交事务时,会先检查版本号,如果发现版本不同时,程序会出现错误。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值