1.原子性
事务应当是一个完整的操作,事务的各个元素是整体,不可分割的,事务中的所以元素应当作为整 体一并提交或回滚,其中事务中的任何元素失败则整个事务失败。
2.一致性
事务完成时数据必须必须处于一致的状态(完成立即同步),事务开始前数据库中存储处于一致状态,事务进行时有可能数据不是一致状态。
3.隔离性
当数据库产生并发时,每个事务是相互独立的,相互隔离的,它不应该以任何方式影响或被影响其他事务,当两个事务都会对一个数据访问是,事务不会并行而是串行。
4.持久性
提交及永久修改,系统无论发生什么故障事务处理完的结果都将无法回滚
Mysql事务是默认提交的,SQL语句提交即事务提交
BEGIN或START TRANSACTION #开始
COMMIT #提交
ROLLBACK #回滚
SAVEPOINT identifier #设置一个名为 identifier 回滚点,类似快照,如果有相同名的回滚点,新的回滚点会将老回滚点覆盖
RELEASE SAVEPOINT identifier
ROLLBACK TO identifier #回滚到标记点
SET TRANSACTION
1、脏读:读取到其他事务未提交的数据,这些数据以意味着可能回滚,不稳定,最终有可能不会存在数据库中,也就是读到未存在的数据。
例:
事务B在执行事务中遵守一致性原则在事务执行时修改了数据,但未曾提交,此时事务A读取了B未提交的数据,此时如果事务B回滚那么就出现脏读的现象
2.不可重复读:一个事务内两个相同的查询返回不同的数据,应为前一个查询在查的时候还是原数据,但后一个查询时却遭到了其他事务的修改查询的不是原数据。
例:
事务A里面有两个select * from table;
一个是查询时出现 10
此时事务B提交了个数据给table 此时table里面数据为80
事务A再次select * from table时查询出为80和之前的10不一致
3.幻读:数据A对一个整体性的内容(字段)进行修改时,还没来得及提交B突然插入几行数据并且在A之前提交了,等A提交玩完查询时发现有几条数据没进行修改且相对之前好像数据不一样了,感觉像做梦一样
4.丢失更新:两个事务同时读取同一条记录,A先修改,此时B并不知道A修改了,此时B就会将A的数据覆盖
我们可以看到上面应为隔离不当导致的一系列问题,所以我们可以设置事务隔离级别对错误进行控制
(1 ) read uncommitted(未提交读)︰读取尚未提交的数据﹔不解决脏读
允许脏读,其他事务只要修改了数据,即使未提交,本事务也能看到修改后的数据值。也就是可能读取到其他会话中未提交事务修改的数居。
(2) read committed(提交读):读取已经提交的数据:可以解决脏读只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别〈不重复读)。
( 3) repeatable read(可重复读 )﹔重读读取:可以解决脏读和不可重复读-mysql默认的可重复读。无论其他事务是否修改并提交了数据,在这个事务中看到的数据值始终不受其他事务影响
( 4) serializable:串行化:可以解决脏读不可重复读和虚读-相当于锁表完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞。mysql默认的事务处理级别是 repeatable-read ,而oracle和sQL Server是 read committed
事务隔离级别作用一般分两种:
全局级:对所有会话有效
会话级:对当前会话有效
查询全局事务隔离级别:
show global variables like '%isolation%';
select @@global.tx_isolation;
查询会话事务隔离等级
show session variables like '%isolation%';
select @@session.tx_isolation;
select @@tx_isolation;
设置全局事务隔离级别
set global transaction isolation level read uncommitted;
设置会话事务隔离级别
set session transaction isolation level read committed;
事务控制语句:
显式地开启一个事务
BEGIN或STARTTRANSACTION
提交事务,并使已对数据库进行的所有修改变为永久性的
COMMIT或COMMIT WORK
回滚会结束用户的事务,并撤销正在进行的所有未提交的修改
ROLLBACK或ROLLBACK WORK:
使用SAVEPOINT允许在事务中创建一个回滚点,一个事务中可以有多个SAVEPOINT:"s1"代表回滚点名称
SAVEPOINT S1
把事务回滚到标记点。
ROLLBACK TO [ SAVEPOINT] s1
使用set设置控制事务
SET AUTOCOMMIT=0;
#禁止自动提交l
SET AUTOCOMMIT=l;
#开启自动提交,Mysql默认为1
SHOW VARIABLES LIKE 'AUTOCOMMIT";
#查看Mysql中的AUTOCOMMIT值
如果没有开启自动提交,当前会话连接的mysql的所有操作都会当成一个事务直到你输入rollback|commit;当前事务才算结束。当前事务结束前新的mysql连接时无法读取到任何当前会话的操作结果。
如果开起了自动提交,mysql会把每个sql语句当成一个事务,然后自动的commit。
当然无论开启与否,begin; commitlrollback;都是独立的事务。