Spring – Ders 24 Spring Transactions – 02

Merhaba Arkadaslar,
Bir onceki yazimizda Transaction ve ACID kavramindan bahsetmistik. Bir kac yazi boyunca Transaction konusuna devam edecegiz. Bu yazida Spring Transaction Manager’lari gorecegiz ve JDBC uzerinde bir uygulamasini inceleyecegiz. Onumuzdeki yazilarda diger Transaction Manager’leri kullanip ornek uygulamalar yapacagiz.

Spring’de Transaction’lari Local Transaction ve Global Transacion olmak uzere kategorelendirmeye sokabiliriz. Basit olarak Local Transaction , tek makine uzerindeki ornegin bir JDBC baglantisi icin gerekli transaction olarak dusunebiliriz. Global Transaction yapisinda ise isin icine dagitik sistemler(distributed system) girmektedir.

Bir diger kategorelendirme olarak Transaction’lar Programmatic Transaction ve Declarative Transaction olarak 2ye ayrilirlar. Bu yazimizda oncelikle Programmatic Transaction yapisina uygun sekilde bir ornek yapacagiz. Bir sonraki yazida ise Declarative Transaction’i inceleyecegiz.

Programmatic Transaction yaklasiminda , transaction yonetimini source code/kaynak kod icerisinde kodlama ile yapmamizi saglar. Bu yaklasim flexibility(esneklik) saglarken, surdurulebilirlik/bakim (maintain) zorlasmaktadir.

Spring , transaction yonetimi icin bir cok transaction manager saglar. Bu uygulamimizda DataSourceTransactionManager i kullanacagiz.

spring transaction manager

Uygulamimiz icin MySQL de yeni bir Schema olusturalim ; transaction adini verelim. Daha sonrasinda 2 tane tablo olusturacagiz ;

CREATE TABLE Student(
   ID   INT NOT NULL AUTO_INCREMENT,
   NAME VARCHAR(20) NOT NULL,
   AGE  INT NOT NULL,
   PRIMARY KEY (ID)
);

CREATE TABLE Marks(
   SID INT NOT NULL,
   MARKS  INT NOT NULL,
   YEAR   INT NOT NULL
);

Daha once Student sinifini kullanmistik bu sinifi biraz daha genisleterek;

StudentMarks.java

package erguder.levent._24.jdbc.programmatic.transaction;
public class StudentMarks {
	private Integer age;
	private String name;
	private Integer id;
	private Integer marks;
	private Integer year;
	private Integer sid;
// getter setter

}

Dao arabirimizi inceleleyelim;

StudentDao.java

package erguder.levent._24.jdbc.programmatic.transaction;

import java.util.List;
import javax.sql.DataSource;

public interface StudentDAO {

	/*
	 Bu metot ile db baglantisi saglamak icin initialize islemini gerceklestiriyoruz
	 */
	public void setDataSource(DataSource ds);

	/**
	Student ve Marks tablolarina kayit eklemek icin.
	 */
	public void create(String name, Integer age, Integer marks, Integer year);

	/**
	 Student ve Marks tablosundan kayitlari almak icin kullanacagiz.
	 */
	public List<StudentMarks> listStudents();
}

Simdi de arabirimimizi uygulayalim;

StudentJDBCTemplate.java

package erguder.levent._24.jdbc.programmatic.transaction;

import java.util.List;

import javax.sql.DataSource;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

public class StudentJDBCTemplate implements StudentDAO {
	private DataSource dataSource;
	private JdbcTemplate jdbcTemplateObject;
	private DataSourceTransactionManager transactionManager;

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
		this.jdbcTemplateObject = new JdbcTemplate(dataSource);
	}

	public void setTransactionManager(
			DataSourceTransactionManager transactionManager) {
		this.transactionManager = transactionManager;
	}

	public void create(String name, Integer age, Integer marks, Integer year) {

		TransactionDefinition def = new DefaultTransactionDefinition();
		TransactionStatus status = transactionManager.getTransaction(def);

		try {
			// Student tablosuna yeni kayit ekle
			String SQL1 = "insert into Student (name, age) values (?, ?)";
			jdbcTemplateObject.update(SQL1, name, age);

			// Student tablosuna eklenen son kaydin idsini getir ve Marks
			// tablosu
			// icin kullan
			String SQL2 = "select max(id) from Student";
			int sid = jdbcTemplateObject.queryForInt(SQL2);

			String SQL3 = "insert into Marks(sid, marks, year) "
					+ "values (?, ?, ?)";
			jdbcTemplateObject.update(SQL3, sid, marks, year);

			System.out.println("Created Name = " + name + ", Age = " + age);

			transactionManager.commit(status); // transaction yolundaysa commit

		} catch (DataAccessException e) {
			System.out.println("Transaction da Hata olustu, Transaction geri alindi.");
			transactionManager.rollback(status);
			throw e;
		}
		return;
	}

	public List<StudentMarks> listStudents() {
		String SQL = "select * from Student, Marks where Student.id=Marks.sid";

		List<StudentMarks> studentMarks = jdbcTemplateObject.query(SQL,
				new StudentMarksMapper());
		return studentMarks;
	}
}

Onceki yazilarda DataSource ve JdbcTemplate ‘i incelemistik. Bu ornegimizde dikkat ederseniz transaction manager olarak DataSourceTransactionManager’i kullandik.

RowMapper arabirim uygulamasini daha onceki orneklerde de yapmistik ;

StudentMarksMapper.java

package erguder.levent._24.jdbc.programmatic.transaction;

import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;

public class StudentMarksMapper implements RowMapper<StudentMarks> {
	public StudentMarks mapRow(ResultSet rs, int rowNum) throws SQLException {

		StudentMarks studentMarks = new StudentMarks();

		studentMarks.setId(rs.getInt("id"));
		studentMarks.setName(rs.getString("name"));
		studentMarks.setAge(rs.getInt("age"));
		studentMarks.setSid(rs.getInt("sid"));
		studentMarks.setMarks(rs.getInt("marks"));
		studentMarks.setYear(rs.getInt("year"));

		return studentMarks;
	}
}

xml kofigurasyonumuz;

tutorial_24.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">

   <!-- data source -->
   <bean id="dataSource" 
      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
      <property name="url" value="jdbc:mysql://localhost:3306/transaction"/>
      <property name="username" value="root"/>
      <property name="password" value=""/>
   </bean>

   <!-- TransactionManager -->
   <bean id="transactionManager" 
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource"  ref="dataSource" />    
   </bean>

   <!-- studentJDBCTemplate bean -->
   <bean id="studentJDBCTemplate"
      class="erguder.levent._24.jdbc.programmatic.transaction.StudentJDBCTemplate">
      <property name="dataSource"  ref="dataSource" />
      <property name="transactionManager"  ref="transactionManager" />    
   </bean>

</beans>

test sinifimiz;

TransactionManagerTest.java

package erguder.levent._24.jdbc.programmatic.transaction;

import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TransactionManagerTest {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("tutorial_24.xml");

      StudentJDBCTemplate studentJDBCTemplate = 
      (StudentJDBCTemplate)context.getBean("studentJDBCTemplate");

      System.out.println("------Kayit Ekleme--------" );
      studentJDBCTemplate.create("Levent", 24, 50, 2013);
      studentJDBCTemplate.create("Recep", 24, 75, 2011);
      studentJDBCTemplate.create("Burak", 23, 100, 2012);
      studentJDBCTemplate.create("Ozkan", 25, 99, 2013);

      System.out.println("------Listele--------" );
      List<StudentMarks> studentMarks = studentJDBCTemplate.listStudents();
      for (StudentMarks record : studentMarks) {
         System.out.print("ID : " + record.getId() );
         System.out.print(", Name : " + record.getName() );
         System.out.print(", Marks : " + record.getMarks());
         System.out.print(", Year : " + record.getYear());
         System.out.println(", Age : " + record.getAge());
      }
   }
}

Ornegimizi calistirip test edelim ;

record

Yazimi burada sonlandiriyorum.

kaynak kodlar: SpringProject_v24

Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
injavawetrust

Print Friendly, PDF & Email

Leave a Reply

Your email address will not be published. Required fields are marked *