Spring 常见问答

BeanFactory 和 ApplicationContext 的区别
1. ApplicationContext 是 BeanFactory 的扩展,提供了更丰富的功能,如 AOP ,国际化,事件通知等;
2. 在使用上, BeanFactory 更面向编码, ApplicationContext 更面向配置;
3. BeanFactory 采用懒加载, ApplicationContext 在应用程序启动时加载所有 Bean 。

Spring 注入的几种方式
1. Set 注入
2. 构造器注入
  <bean name="xx" class="yy">
    <constructor-arg index="0" ref="aa"></constructor-arg>
    <constructor-arg index="1" ref="bb"></constructor-arg>
  </bean>
3. 静态工厂方法注入
  public class DaoFactory {
    public static final UserDao getUserDaoImpl() {
      ......
    }
  }
  <bean name="xx" class="yy">
    <property name="userDao" ref="userDao">
  </bean>
  <bean name="userDao" class="DaoFactory" factory-method="getUserDaoImpl" />
4. 实例工厂方法注入
  public class DaoFactory {
    public UserDao getUserDaoImpl() {
      ......
    }
  }
  <bean name="xx" class="yy">
    <property name="userDao" ref="userDao">
  </bean>
  <bean name="daoFactory" class="DaoFactory" />
  <bean name="userDao" factory-bean="daoFactory" factory-method="getUserDaoImpl" />

Spring 事务的隔离级别( Isolation )
1. ISOLATION_DEFAULT: 这是一个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。
2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。
4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
5. ISOLATION_SERIALIZABLE: 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。

什么是脏读,不可重复读,幻读?
脏读:指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据, 那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。
不可重复读:指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
幻读:指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

Spring 事务传播行为( Propagation )
PROPAGATION_REQUIRED: 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS: 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY: 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW: 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED: 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER: 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED: 它与 PROPAGATION_REQUIRES_NEW 的区别是, PROPAGATION_REQUIRES_NEW 另起一个事务,将会与它的父事务相互独立,而 Nested 事务和它的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,它也要回滚的。

共享锁和排它锁
原文: http://www.cnblogs.com/edwinchen/p/4171866.html
共享锁类似于 Java 里面的读写锁: 允许多个线程同时读,但只允许一个线程写。读的时候写线程被阻塞,写的时候读线程被阻塞。
排它锁类似于普通的 synchronized 或者普通的 Lock ,永远只有一个线程在工作。
如果是在 read committed 或 repeatable read 下,普通的 select 语句并不会进行锁操作,其它 session 可以照常更新或插入操作。所以在这里面就可以发现,如果只是普通 select ,不管在不在事务中, mysql 都不会将 select 加锁,所以根本无法阻止其它事务插入记录。
select ...... for update 会加上排它锁,防止这个问题。

表锁和行锁
原文: http://www.jb51.net/article/50047.htm
页级:引擎 BDB 。
表级:引擎 MyISAM ,理解为锁住整个表,可以同时读,写不行。
行级:引擎 INNODB ,单独的一行记录加锁。
表级,直接锁定整张表,在你锁定期间,其它进程无法对该表进行写操作。如果你是写锁,则其它进程则读也不允许。
行级,仅对指定的记录进行加锁,这样其它进程还是可以对同一个表中的其它记录进行操作。
页级,表级锁速度快,但冲突多;行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。

猜你喜欢

转载自dsxwjhf.iteye.com/blog/2293660