Spring MVC で複数データソースを扱った場合の挙動を調べてみた
Spring MVC で扱うデータソースが2つある時、片方だけトランザクションを張った場合にもう片方の更新が反映されない、という問題に直面したので色々試してみた。Spring 初心者すぎて辛い。
環境
Spring 3.2.4
元々のソース
例えば user と groupというテーブルがあり、それぞれに対して更新する処理を書いていた。
#!java
@Service
public class HogeService {
@Transactional
public void update() {
userService.update();
groupService.update();
}
}
ここで、user と group とでDBを分けることになり、DataSource と TransactionManager を複数に分けた際、デフォルトの user は更新されるが group の更新がされなくなった。この挙動自体はまぁ当然。
(1) groupService 側にも @Transactional を指定してみる
これで両方トランザクションが張られて正常に動作した。
#!java
@Service
public class GroupService {
@Transactional(“group")
public void update() {
// update...
}
}
(2) afterCommit を利用してみる
今回は group 側にトランザクションを張らなくても良いケースだったので、試しに TransactionSynchronizationAdapter#afterCommit を利用してみた。
#!java
@Service
public class HogeService {
@Transactional
public void update() {
userService.update();
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
groupService.update();
}
}
);
}
}
これでうまくいくかと思ったが、group への更新は反映されなかった。何かイメージと違う。afterCommit の後に何か処理が走っているのか。
(3) user、group への更新処理をメソッド毎分ける
StackOverflow とか Spring 関連の記事を見ていると、結局これに落ち着きそうな感じ。もちろん想定通りに動作する。
#!java
@Service
public class HogeService {
@Transactional
public void updateUser() {
userService.update();
}
@Transactional(“group")
public void updateGroup() {
groupService.update();
}
}
時間も無く、結局うまいやり方が見つからないので、(3) の実装で一旦落ち着いた。
Java8 を触ってみる
Java8 が正式リリースされたので、新機能がどんなものか触ってみた。
続きを読むEclipse 開発環境構築手順メモ (Mac OS X)
Eclipse をダウンロード
http://www.eclipse.org/downloads/
執筆時点では Kepler SR2 が最新でした。
eclipse-xxx.tar.gz を解凍し、好きな場所に配置
個人的には ~/dev/eclipse/kepler とかディレクトリ切ってます。
Eclipse を起動して各種設定を行う
- 行番号を表示する
- 文字コードの設定を UTF-8 にする
- Code Assist のショートカットキーを Command + Space に変更する
- Project Explorer ではなく Package Explorer を使う
- Package Presentation を Hierarchical に変更する
必要に応じてプラグインをインストール
- FindBugs
- Checkstyle
- Subversive
- EGit
とか。
はじめての Node.js (3)
今回は MySQL との接続周りを確認。 詳細は https://github.com/felixge/node-mysql の README 見たほうが早い。 MongoDB は今回は割愛。
Node.js からデータベースにアクセスする
- 利用したい DB に対応するモジュールを使う
<サンプルソース>
#!js
// create connection.
var conn = mysql.createConnection({
user: 'nodejs_study',
password: 'nodejs_study',
database: 'nodejs_study'
});
// connect
conn.connect();
// create table.
conn.query('CREATE TABLE IF NOT EXISTS users (' +
'id INT(11) NOT NULL AUTO_INCREMENT,' +
'name VARCHAR(255),' +
'PRIMARY KEY (id)' +
')');
// execute query.
conn.query('INSERT INTO users(name) VALUES(?)', ['foo'], function(err, result) {
console.log(result.insertId);
});
// streaming query rows.
var query = conn.query('SELECT * FROM users;');
query.on('result', function(row) {
console.log(row);
});
// end
conn.end();
はじめての Node.js (2)
続き。今回はデバッグまで。
シンプルなWebアプリケーションを作る
- http モジュールを利用してWebアプリケーションを書いてみる
- url モジュールで URL の解析が可能
- querystring でクエリ文字列の解析が可能
- multipart については標準モジュールが無いらしい
<サンプルソース>
#!js
var http = require('http'),
url = require('url'),
querystring = require('querystring');
var server = http.createServer();
server.on('request', function(request, response) {
response.setHeader('Content-Type', 'text/html');
response.writeHead(200);
response.write('<form method="post" action="/"><input type="text" name="value"/><input type="submit"/></form>');
if (request.method === 'POST') {
var data = '';
request.on('data', function(chunk) {
data += chunk;
});
request.on('end', function() {
console.log(querystring.parse(data));
});
}
response.end();
});
server.listen(8080, '127.0.0.1');
バイナリデータの操作とファイルの入出力
個人的にこの辺りは散々使っているので割愛。