1.事务定义?
事务(transaction)是一个不可分割逻辑工作单元.例如
转账,存钱,下订单等都可以看成一个事务.
2.事务的四大特性:
1)原子性(事务逻辑中的操作要么都执行要么不执行.)
2)一致性(事务前后数据状态应该是一致的);
3)隔离性(多个事务并发执行时应是相互隔离的)
4)持久性(事务一旦提交或回滚事务状态将会持久性发生变化)
多个事务并发执行时可能导致问题
2.1)脏读(读取了别人未提交数据)
A: start transaction
insert into book values(1,......)
....
B: start transaction
select * from book; 显示有1
A: rollback;//此时B看到的1这条数据就称之为脏数据.
出现此问题的原因:事务的隔离级别可能是
read uncommited
解决方案:将事务隔离级别设置为read commited;
2.2)不可重复读(一个事务内部多次读取的数据结果不一致.)
A: start transaction
select count from book where id=1001; 100
B: start transaction
update book set count-1 where id=1001;
.....
A:select count from book where id=1001; 99
假如事务的隔离级别为read commited 可能还会导致
一个事务内部多次读取出现不一致的现象.此时可以将
事务的隔离级别设置为Repeatable Read(这是mysql
中默认的隔离级别.)
2.3)幻影读(修改了本事务看不到的数据)
首先事务的隔离级别为repeatable read
B:事务开启(手动提交)
select * from book;
1 java 10
2 android 20
A:事务开启(手动提交)
insert into book (3,……);
insert into book (5,……);
commit; ok
B:事务查询
select * from book;
1 java 10
2 android 20
B:事务执行
delete from book where id=3;//删除OK
update book set count=21 where id=5; //ok
出现的这种现象通常称之为幻读.解决幻读问题
需要将事务的隔离级别设置为Serializable
2.4) 丢失更新
现有一个购书案例:A&B同时购书
A 事务:
step01:查询 book(100)
step02:购买 update book set count=100-1 where id=1001
B 事务: book(100)
step01:查询 book(100)
step02:购买 update book set count=100-1 where id=1001
这个现象可以理解为丢失更新,那如何解决这个问题?
可以通过加锁的机制解决这个问题,那如何加锁?(排他锁,乐观锁)
典型的排他锁(悲观):
select * from book where id=1001 for update;
典型的乐观锁:一般是在表中添加version字段(版本):
3. 数据库事务的隔离级别
多个事务并发执行时通常会借助设置事务的隔离级别来避免
脏读,不可重复读,幻影读等现象.mysql中支持的事务隔离级别
有如下四中:
1)Read Uncommitted
2)Read Committed
3)Repeatable Read
4)Serializable
mysql中如何查看和设置事务的隔离级别.
1).查看当前会话隔离级别
select @@tx_isolation;
2).查看系统当前隔离级别
select @@global.tx_isolation;
3).设置当前会话隔离级别,例如
set session transaction isolation level repeatable read;
4.设置系统当前隔离级别,例如
set global transaction isolation level repeatable read;
5.命令行,开始事务时(设置事务手动提交方式)
set autocommit=off 或者 start transaction
4.Spring 中事务控制
Spirng中的事务控制有两种实现:
1)编程式事务(基本不用)
Connection conn
try{
conn=DbUitl.getConnection();
conn.setAutoCommit(false);
dao.updateObject(...)
dao.saveObject(...)
conn.commit();
}catch(Exception e){
conn.rollback();
}finally{
conn.close();
}
2)声明式事务(重点使用):
将编程事务的那部分代码交给spring底层实现,然后通过
AOP机制将事务控制代码植入到业务层.
spring 中的声明式事务处理方式:两种方式
a)基于xml
b)基于注解(重点掌握):通过@Transactional
实现步骤:
1)配置文件中启用事务配置
<!-- 配置spring的生命式事务管理 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--设置注解驱动的事务管理 -->
<tx:annotation-driven
transaction-manager="txManager"/>
2)业务类中通过@Transactional注解定义事务
5.Spring 中事务的传播特性
何为传播特性?
当一个事务业务方法调用另外一个事务业务方法时
事务的执行方式,称之为传播特性.
常用传播特性:
@Transactional(propagation=Propagation.REQUIRED) 如果没有事务创建新事务, 如果当前有事务参与当前事务
@Transactional(propagation=Propagation.REQUIRES_NEW)
必须是新事务, 如果有当前事务, 挂起当前事务并且开启新事务.
…….
1.系统管理模块下都有哪些子模块
1)组织结构管理
a)表设计如何实现(自关联)
b)展现形式(树结构)
2)菜单管理(记录系统中的所有资源(url),例如按钮,菜单)
a)表设计如何实现(自关联)
字段:id,name,parentId,url,type,sort,note,…..
b)展现形式(树结构:zTree,treeGrid)
3)角色管理(便于对系统用户按角色管理)
a)表结构如何实现(单表结构)
b)展现形式(一般的table)
4)用户管理(登录用户的管理)
a)表结构(单表)
b)…………………………..
2.对象模块关系分析
1)用户与角色是什么关系?(many2many)
a)一个用户可以有多个角色
b)一个角色也可以对应个用户
多对多的关系,在表设计时如何实现? 借助中间表(关系表)
User
userId roleId
1 —–2
1 —–3
Role
roleId userId
1 ——-1
1——–2
UserRole (关系表,在此表中记录对象关系)
userId,roleId
1 1
2 2
3 1
2 3
primary key(userId,roleId) 联合主键
2)角色与菜单有关系吗,什么关系? (many2many)
1) 一个角色可以有多个菜单的访问权
2)一个菜单也可以被多个角色访问.
这种关系要借助谁来维护?(中间表,关系表)
3)用户与组织机构是什么关系?(many2one)
对于这种关系关系维护方由谁来维护?多的一方.
Shiro 框架
1.如何自己实现项目中的权限控制?
1.1 权限控制包含的内容:
1)检测用户是否登录? (认证检测)
a)在控制层获得session对象
b)通过session对象获取用户信息,
有则表示已登录,没有则跳转到登录页面
2)检测用户是否有权限访问此模块?(权限检测)
a)根据用户信息获取角色信息
b)根据角色信息查询菜单信息
1.2) 权限控制的实现?
1)认证检测的实现可考虑过滤器或拦截器中实现.
2)权限检测的实现可考虑在业务层借助动态代理或AOP实现.
2.Shiro 框架在项目中的应用?
1)Shiro 是什么? apache 提供的一个安全框架.
2)Shiro 具备什么功能?
认证检测,权限检测,缓存处理,加密处理等.
3)Shiro 基本架构?(认证,授权等流程分析)
4)Shiro 核心API?(Subject,SecurityManager,Realm,….)