事物 @Transactional
转载:http://www.cnblogs.com/kristain/articles/2038397.html
一、什么是事务
- 原子性。即不可分割性,事务要么全部被执行,要么就全部不被执行。如果事务的所有子事务全部提交成功,则所有的数据库操作被提交,数据库状态发生转换;如果有子事务失败,则其他子事务的数据库操作被回滚,即数据库回到事务执行前的状态,不会发生状态转换。
- 一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态。
- 隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务,即在事务正确提交之前,它可能的结果不应显示给任何其他事务。
- 持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。
运行嵌入式SQL应用程序或脚本,在可执行SQL语句第一次执行时(在建立与数据库的连接之后或在现有事务终止之后),事务就会自动启动。在启动事务之后,必须由启动事务的用户或应用程序显式地终止它,除非使用了称为自动提交(automatic commit)的过程(在这种情况下,发出的每个单独的SQL语句被看做单个事务,它一执行就被隐式地提交了)。
在大多数情况下,通过执行COMMIT或ROLLBACK语句来终止事务。当执行COMMIT语句时,自从事务启动以来对数据库所做的一切更改就成为永久性的了-- 即它们被写到磁盘。当执行ROLLBACK语句时,自从事务启动以来对数据库所做的一切更改都被撤销,并且数据库返回到事务开始之前所处的状态。不管是哪种情况,数据库在事务完成时都保证能回到一致状态。
一定要注意一点:虽然事务通过确保对数据的更改仅在事务被成功提交之后才成为永久性的,从而提供了一般的数据库一致性,但还是须要用户或应用程序来确保每个事务中执行的SQL操作序列始终会导致一致的数据库。
二、数据库系统支持两种事务模式:
- 自动提交模式:每个SQL语句都是一个独立的事务,当数据库系统执行完一个SQL语句后,会自动提交事务。
- 手动提交模式:必须由数据库客户程序显示指定事务开始边界和结束边界。
注:MySQL中数据库表分为3种类型:INNODB、BDB和MyISAM,其中MyISAM不支持数据库事务。MySQL中create table 语句默认为MyISAM类型。
三、对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题,这些并发问题可归纳为以下几类:
- 第一类丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖。
- 脏读:一个事务读到另一个事务为提交的更新数据。
- 虚读:一个事务读到另一个事务已提交的新插入的数据。
- 不可重复读:一个事务读到另一个事务已提交的更新数据。
- 第二类丢失更新:这是不可重复读中的特例,一个事务覆盖另一个事务已提交的更新数据。
四、隔离级别
当数据库系统采用read Commited隔离级别时,会导致不可重复读喝第二类丢失更新的并发问题,可以在应用程序中采用悲观锁或乐观锁来避免这类问题。从应用程序的角度,锁可以分为以下几类:
- Serializable(串行化):一个事务在执行过程中完全看不到其他事务对数据库所做的更新。
- Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他事务对已有记录的更新。
- Read Commited(读已提交数据):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且能看到其他事务已经提交的对已有记录的更新
- Read Uncomitted(读未提交数据):一个事务在执行过程中可以拷打其他事务没有提交的新插入的记录,而且能看到其他事务没有提交的对已有记录的更新。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以有优先考虑把数据库系统的隔离级别设为Read Commited,它能够避免脏读,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
当数据库系统采用read Commited隔离级别时,会导致不可重复读喝第二类丢失更新的并发问题,可以在应用程序中采用悲观锁或乐观锁来避免这类问题。从应用程序的角度,锁可以分为以下几类:
A.悲观锁:指在应用程序中显示的为数据资源加锁。尽管能防止丢失更新和不可重复读这类并发问题,但是它会影响并发性能,因此应该谨慎地使用。
B.乐观锁:乐观锁假定当前事务操作数据资源时,不回有其他事务同时访问该数据资源,因此完全依靠数据库的隔离级别来自动管理锁的工作。应用程序采用版本控制手段来避免可能出现的并发问题。
五、悲观锁有两种实现方式。
A.在应用程序中显示指定采用数据库系统的独占所来锁定数据资源。SQL语句:select ... for update,在Hibernate中使用get,load时如session.get(Account.class,new Long(1),LockMode,UPGRADE)
B.在数据库表中增加一个表明记录状态的LOCK字段,当它取值为“Y”时,表示该记录已经被某个事务锁定,如果为“N”,表明该记录处于空闲状态,事务可以访问它。增加锁标记字段就可以实现。
利用Hibernate的版本控制来实现乐观锁
乐观锁是由程序提供的一种机制,这种机制既能保证多个事务并发访问数据,又能防止第二类丢失更新问题。
在应用程序中可以利用Hibernate提供的版本控制功能来视线乐观锁,OR映射文件中的<version>元素和<timestamp>都具有版本控制的功能,一般推荐采用<version>
事物 @Transactional的更多相关文章
- springboot事物回滚
要添加事物 必须在方法上添加 @Transactional 注解 如果需要事物回滚有两个条件 1.方法中有异常或者主动抛异常 2.主动去回滚 TransactionAspectSupport.curr ...
- java陷阱之spring事物管理导致锁无效
模拟锁情况无效 1.创建一个表 SET NAMES utf8mb4; ; DROP TABLE IF EXISTS `demo`; CREATE TABLE `demo` ( `id` ) NOT N ...
- java陷阱之spring事物未提交和回滚导致不可预知问题
案发现场 //防止全局配置了 所以这里定义sprnig 不托管事物 @Transactional(propagation = Propagation.NOT_SUPPORTED) public boo ...
- SpringBoot事物Transaction实战讲解教程
前言 本篇文章主要介绍的是SpringBoot的事物Transaction使用的教程. SpringBoot Transaction 说明:如果想直接获取工程那么可以直接跳到底部,通过链接下载工程代码 ...
- oracle大数据量。表分区提示查询效率
现在业务有一张usertrack 日志记录表.每天会产生30万条数据.数据量大查询效率会非常慢 所以我考虑通过表分区来提示效率 逻辑上是一张表.但是分区后会按照分区条件将数据分在不同的物理文件 优点 ...
- 最近项目中使用Spring data jpa 踩过的坑
最近在做一个有关OA项目中使用spring data JPA 操作数据库,结果遇到了补个不可思议的麻烦.困惑了好久. 首先看一下问题吧,这就是当时测试“设置角色时,需要首先删除该用户已经拥有的角色时” ...
- springboot 中使用事务
直接在service 层的方法上加上@Transactional 注解就ok. 注意事项: 1.Spring 基于注解的声明式事物 @Transactional 默认情况下只会对运行期异常(java. ...
- SpringBoot------集成MyBatis
1.pom.xml文件添加MyBatis和MySQL等依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns: ...
- SpringBoot------JPA连接数据库
步骤: 1.在pom.xml文件下添加相应依赖包 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=& ...
随机推荐
- 查询oracle中所有用户信息 禁用用户
----查询oracle中所有用户信息 ----1.查询数据库中的表空间名称 ----1)查询所有表空间 select tablespace_name from dba_tablespaces; se ...
- 【算法与数据结构】并查集 Disjoint Set
并查集(Disjoint Set)用来判断已有的数据是否构成环. 在构造图的最小生成树(Minimum Spanning Tree)时,如果采用 Kruskal 算法,每次添加最短路径前,需要先用并查 ...
- SpringMVC +Spring + MyBatis + Mysql + Redis(作为二级缓存) 配置
转载:http://blog.csdn.net/xiadi934/article/details/50786293 项目环境: 在SpringMVC +Spring + MyBatis + MySQL ...
- python获取csv文本的某行或某列数据
#coding = 'utf-8' import csv # 使用list,只能读取列,而且是全文读取,csv.reader会自动把CSV内容生成数组 ''' df = csv.reader(open ...
- pyinstaller如何将自己写的模块一并打包到exe中
使用pyinstaller命令 pyinstaller -F main.py 打包时,若mian.py代码中存在引入自己写的模块,而打包成exe文件时,并不会自动引入自己写的模块,打包成功后,点击打开 ...
- 应用安全 - 中间件漏洞 - Nostromo
CVE-2011-0751 Date: 2011.3 类型: 路径遍历 PoC:https://nvd.nist.gov/vuln/detail/CVE-2011-0751 CVE-2019-162 ...
- 【Qt开发】【VS开发】【Linux开发】OpenCV、Qt-MinGw、Qt-msvc、VS2010、VS2015、Ubuntu Linux、ARM Linux中几个特别容易混淆的内容
[Qt开发][VS开发][Linux开发]OpenCV.Qt-MinGw.Qt-msvc.VS2010.VS2015.Ubuntu Linux.ARM Linux中几个特别容易混淆的内容 标签:[Qt ...
- echars 饼图 --》二次封装
<template> <!-- 饼状图 1. 调用页面引入 import EcharsPie from '@/components/echarsPie.vue'; 注:自定义的组件名 ...
- docker--docker仓库
8 docker仓库 Docker仓库(Repository)类似与代码仓库,是Docker集中存放镜像文件的地方. 8.1 docker hub 1.打开https://hub.docker.com ...
- 【扩展事件】跟踪超过3秒的SQL
msdn 扩展事件:点击打开链接 转自:https://blog.csdn.net/yenange/article/details/52592814 -- 删除事件会话 IF EXISTS(SELEC ...