Reputation: 351
Code for Main.java:
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();
}
}
Code for 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();
}
}
Code for UserDAOImpl.java:
@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;
}
}
Code for 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>
When run the above main class, theoretically thread one will start first and it has to lock the table USER
(because isolation = Isolation.SERIALIZABLE
) and when the thread two running it has to wait till the lock released from table USER
without read the table from table, but when I run this code it is reading the table and print without wait for first transaction to finish. Why does not USER
table lock work even thought the Isolation is SERIALIZABLE
???
Upvotes: 1
Views: 3038
Reputation: 154
I think The Solution is..
In case of reads the lock will be shared among Multiple Thread (Shred Mode). so the 'select' query is executing properly.If you Try with an update/delete query you will get the scenario what you thinking(The another Thread has to wait until first one complete). try in this way.
Upvotes: 1
Reputation: 351
I got the answer to this question. here problem was time delay between thread one and tow, here I have given time delay as 100ms but this delay is not enough because before insertUser() get the table lock getUsers() occupy the lock and get the data and process it, so once I changed the time delay as 1000ms this problem was resolved. so insertUser() occupied the lock and getUsers() waited till insertUser() finished and commit the insertion part.
Upvotes: 1