mybatis事物如何避免脏读_mysql事务练习demo

#TCL

/*

Transaction Control Language 事务控制语言

事务:

一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行。

案例:转账

zhang3  1000

li41000

update 表1 set zhang3的余额=500 where name='zhang3'

-- 此时出现问题

update 表2 set li4的余额=1500 where name='li4'

*/

/*

事务的创建:

隐式事务:事务没有明显的开启和结束的标记.

比如insert、update、delete语句.

DELETE FROM 表 WHERE id =1;

显式事务:事务具有明显的开启和结束的标记.

前提:必须先设置MySQL的事务默认设置(关闭自动提交开关).

SET autocommit=0;

(1):开启事务

START TRANSACTION;#可选的

(2):编写事务中的sql语句(SELECT INSERT UPDATE DELETE)

语句1;

语句2;

...

(3):结束事务

<1>:COMMIT;提交事务

<2>:ROLLBACK;回滚事务

SAVEPOINT 回滚点;设置保存点.

*/

-- 事务案例:

-- 创建账户表:

DROP TABLE IF EXISTS account;

CREATE TABLE account(

id INT PRIMARY KEY AUTO_INCREMENT,

`name` VARCHAR(20),

money INT DEFAULT 0

);

-- 添加两条记录

INSERT INTO account VALUES (1, 'zhang3', 1000);

INSERT INTO account VALUES (2, 'li4', 1000);

SELECT * FROM account;

-- 不使用事务,正常转账:

UPDATE account SET money = money-500 WHERE `name` = 'zhang3';

UPDATE account SET money = money+500 WHERE `name` = 'li4';

-- 不使用事务,转账发生问题:

UPDATE account SET money = money-500 WHERE `name` = 'zhang3';

-- 此时发生问题,导致下一句sql无法执行:

UPDATE account SET money = money+500 WHERE `name` = 'li4';

-- 使用事务,封装转账逻辑

-- 关闭自动提交:

SET autocommit=0;

-- 开启事务:

START TRANSACTION;

-- 事务逻辑

UPDATE account SET money = money-500 WHERE `name` = 'zhang3';

UPDATE account SET money = money+500 WHERE `name` = 'li4';

-- 提交事务:

COMMIT;

/*

事务的四大特性:ACID

原子性(Atom):事务是最小的操作单位,不可分割,要么全部成功,要么全部失败.

一致性(Consistency):事务执行之前和执行之后,数据的状态必须保持一致性原则.

如:转账之前和转账之后,总钱数必须一致.

隔离性(Isolation):事务执行时是独立的,不受其他事务影响.

持久性(Durability):事务执行之后,数据状态的改变将是永久的.

*/

/*

事务的并发问题:

1.脏读:事务A读取了一个数据,这个数据是事务B修改的一个数据,此时事务B回滚了,

数据又恢复到原来的值,此时事务A读取的数据就是一个脏数据.

2.不可重复读:

事务A多次读取一个数据,其中有一次这个数据被事务B给修改了,

导致事务A前后两次读取的数据不一致.

3.幻读:

事务A读取(或修改)一个表的数据时,此时事务B向表中添加(或删除)了一条(或多条)

数据,导致事务A执行完之后,发现数据库中竟然还有(或少)数据没读取出来.好像产生

了幻觉一样.

注意:

(1)脏读和幻读比较容易混淆.

(2)脏读侧重数据被修改而导致的数据不准确.

(3)幻读侧重数据被添加或删除而导致的数据个数不一致.

*/

/*

事务的隔离级别:

前提:

(1)事务保证了一个逻辑单位操作的完整性和安全性.要么成,要么败,没有中间结果.

(2)但是事务和事务之间并发操作会出现问题:脏读,不可重复读,幻读.

(3)解决事务并发性需要引入一种策略:事务的隔离级别!

事务4级隔离级别:

(1)读未提交:read-uncommitted

(2)不可重复读:read-committed

(3)可重复读:repeatable-read

(4)串行化:serializable

事务隔离级别能解决的问题:

级别:问题(能否解决)

脏读不可重复读幻读

(1)1级别:read-uncommitted不能不能不能

(2)2级别:read-committed能不能不能

(3)3级别:repeatable-read能能不能

(4)4级别:serializable能能能

注意:

(1)第1级别只是一种级别,不能解决任何事务并发问题.

(2)MySQL默认是第3级别,Oracle默认是第2级别.

(3)级别越低,效率越高,执行速度越快,但是问题发生几率越大.

(4)第4级别,效率最差,数据安全性最好.

(5)级别的选择,根据企业项目需求.

*/

-- MySQL实例:

-- 查看隔离级别

SELECT

@@tx_isolation ;

-- 设置隔离级别

-- SET SESSION|GLOBAL TRANSACTION ISOLATION LEVEL 隔离级别;

SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

-- 设置成最低级别:

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

-- 设置成最高级别:

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

SELECT @@tx_isolation ;

-- 查看数据库引擎:

SHOW ENGINES;

#1.演示事务的使用步骤

SELECT * FROM account;

USE db2;

-- 查看事务自动提交变量:

SELECT @@autocommit;

SET @@autocommit=0;# 关闭自动提交

-- 开启事务

START TRANSACTION;

-- 编写一组事务的语句

UPDATE account SET money = money - 500 WHERE id = 1;

UPDATE account SET money = money + 500 WHERE id = 2;

COMMIT;

-- 结束事务

ROLLBACK;# 要么回滚

COMMIT;# 要么提交

SELECT * FROM account;

#2.delete和truncate的在事务中的区别

-- delete

SET autocommit=0;# 关闭自动提交

# 开启事务

DELETE FROM account;# delete

ROLLBACK;# 回滚

-- truncate

START TRANSACTION;# 开启事务

TRUNCATE account;# TRUNCATE

ROLLBACK;# 回滚

/*

(1)delete删除数据,事务回滚,数据可恢复.

(2)turncate删除数据,事务回滚,数据不可恢复.

*/

#3.演示savepoint 的使用

SET autocommit=0;

START TRANSACTION;

DELETE FROM account WHERE id=25;

SAVEPOINT a;#设置保存点

DELETE FROM account WHERE id=28;

ROLLBACK TO a;#回滚到保存点

SELECT * FROM account;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值