Java spring事务隔离序列化无法工作
Main.java的代码:Java spring事务隔离序列化无法工作,java,spring,isolation-level,transaction-isolation,Java,Spring,Isolation Level,Transaction Isolation,Main.java的代码: public class Main { public static void main(String[] args) { final ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); final UserManager userManager = (UserManager) ctx.getBean("userManagerImp
public class Main {
public static void main(String[] args) {
final ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
final UserManager userManager = (UserManager) ctx.getBean("userManagerImpl");
new Thread() {
public void run() {
User user = new User();
user.setUsername("hari18");
user.setName("haris1");
userManager.insertUser(user);
System.out.println("User inserted!");
}
} .start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread() {
public void run() {
List<User> users = userManager.getUsers();
System.out.println("\nUser list fetched!" + "\nUser count: " + users.size());
for (User user1 : users) {
System.out.println(user1.getUsername());
}
}
} .start();
}
}
公共类主{
公共静态void main(字符串[]args){
final ApplicationContext ctx=新类路径xmlapplicationcontext(“spring.xml”);
final UserManager UserManager=(UserManager)ctx.getBean(“userManagerImpl”);
新线程(){
公开募捐{
用户=新用户();
user.setUsername(“hari18”);
user.setName(“haris1”);
userManager.insertUser(用户);
System.out.println(“用户插入!”);
}
}.start();
试一试{
睡眠(100);
}捕捉(中断异常e){
e、 printStackTrace();
}
新线程(){
公开募捐{
List users=userManager.getUsers();
System.out.println(“\n用户列表已获取!”+”\n用户计数:“+users.size());
for(用户1:用户){
System.out.println(user1.getUsername());
}
}
}.start();
}
}
UserManagerImpl.java的代码:
@Service
@Scope("prototype")
public class UserManagerImpl implements UserManager {
@Autowired
private UserDAO userDAO;
@Override
@Transactional( propagation=Propagation.REQUIRED , isolation=Isolation.SERIALIZABLE)
public void insertUser(User user) {
userDAO.insertUser(user);
}
@Override
@Transactional( propagation=Propagation.REQUIRED , isolation=Isolation.SERIALIZABLE)
public List<User> getUsers() {
return userDAO.getUsers();
}
}
@Service
public class UserDAOImpl extends JdbcDaoSupport implements UserDAO {
@Autowired
public UserDAOImpl(DataSource dataSource) {
setDataSource(dataSource);
}
@Override
public void insertUser(User user) {
getJdbcTemplate().update("INSERT INTO USER (USERNAME, NAME) VALUES (?, ?)",
new Object[] {
user.getUsername(),
user.getName()
}
);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public List<User> getUsers() {
List<User> users = getJdbcTemplate().query("SELECT * FROM USER",new UserMapper());
return users;
}
}
@服务
@范围(“原型”)
公共类UserManagerImpl实现UserManager{
@自动连线
私有UserDAO UserDAO;
@凌驾
@事务性(传播=传播.REQUIRED,隔离=隔离.SERIALIZABLE)
公共void插入器(用户){
userDAO.insertUser(用户);
}
@凌驾
@事务性(传播=传播.REQUIRED,隔离=隔离.SERIALIZABLE)
公共列表getUsers(){
返回userDAO.getUsers();
}
}
UserDAOImpl.java的代码:
@Service
@Scope("prototype")
public class UserManagerImpl implements UserManager {
@Autowired
private UserDAO userDAO;
@Override
@Transactional( propagation=Propagation.REQUIRED , isolation=Isolation.SERIALIZABLE)
public void insertUser(User user) {
userDAO.insertUser(user);
}
@Override
@Transactional( propagation=Propagation.REQUIRED , isolation=Isolation.SERIALIZABLE)
public List<User> getUsers() {
return userDAO.getUsers();
}
}
@Service
public class UserDAOImpl extends JdbcDaoSupport implements UserDAO {
@Autowired
public UserDAOImpl(DataSource dataSource) {
setDataSource(dataSource);
}
@Override
public void insertUser(User user) {
getJdbcTemplate().update("INSERT INTO USER (USERNAME, NAME) VALUES (?, ?)",
new Object[] {
user.getUsername(),
user.getName()
}
);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public List<User> getUsers() {
List<User> users = getJdbcTemplate().query("SELECT * FROM USER",new UserMapper());
return users;
}
}
@服务
公共类UserDAOImpl扩展了JdbcDaoSupport实现了UserDAO{
@自动连线
public UserDAOImpl(数据源数据源){
setDataSource(数据源);
}
@凌驾
公共void插入器(用户){
getJdbcTemplate().update(“插入用户(用户名、名称)值(?,)”,
新对象[]{
user.getUsername(),
user.getName()
}
);
试一试{
睡眠(1000);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
@凌驾
公共列表getUsers(){
List users=getJdbcTemplate().query(“从用户中选择*,新建UserMapper());
返回用户;
}
}
spring.xml的代码:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="com.byteslounge.spring" />
<!-- context:component-scan base-package="com.byteslounge.spring" /-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
当运行上面的主类时,理论上线程一将首先启动,它必须锁定表
USER
(因为isolation=isolation.SERIALIZABLE
),当线程二运行时,它必须等待锁从表USER
中释放,而不从表中读取表,但当我运行此代码时,它正在读取表并打印,而不必等待第一个事务完成。为什么用户
表锁不工作,即使隔离是可序列化的?我得到了这个问题的答案。
这里的问题是线程1和线程2之间的时间延迟,这里我给出了100毫秒的时间延迟,但是这个延迟是不够的,因为在insertUser()获取表锁之前,getUsers()占用锁,获取数据并处理它,所以一旦我将时间延迟更改为1000毫秒,这个问题就解决了。
因此insertUser()占用了锁,getUsers()等待insertUser()完成并提交插入部分。我认为解决方案是 在读取的情况下,锁将在多个线程之间共享(分解模式)。因此,“选择”查询正在正确执行。如果您尝试使用更新/删除查询,您将得到您所想的场景(另一个线程必须等到第一个线程完成)。这样试试看