Entity Framework + Postgresql + VACUUM の覚書
Entity Framework の Postgresql で VACUUM を行うと例外が発生します。
「25001: VACUUM cannot run inside a transaction block」
ソースコード:
どうすれば VACUUM が出来るようになるか。
ヒントはここにありました。
URL:https://stackoverflow.com/questions/926656/entity-framework-with-nolock
テーブル&行のロックを行わないトランザクションを開けば良いようです。
この様にトランザクションレベルを変更したうえでその中のトランザクションで行えばエラーにはなりません。
(Entity Framework内部処理で自動的にトランザクションが実行されてしまうのを防ぐため)
ソースコード:
最終的な完成したソース:
1.Postgresqlからユーザーテーブルのみを取得する
2.コネクションが残っていたら閉じる(isForcedフラグで強制的に閉じるかどうかを判断する)
3.トランザクションレベルをReadUncommittedに設定
4.全テーブルに対してVACUUM&ANALYZEを実行する


検索用:Entity Framework Postgresql VACUUM Tranzaction Unlock バキューム ヴァキューム エラー VACUUM cannot run inside a transaction block
「25001: VACUUM cannot run inside a transaction block」
ソースコード:
using (ExecuteSqlCommand execute = new ExecuteSqlCommand(IPAddress,
Port,
DBName,
UserId,
Password))
{
Database.ExecuteSqlCommand("VACUUM (ANALYZE) public.AAAA;");
}どうすれば VACUUM が出来るようになるか。
ヒントはここにありました。
URL:https://stackoverflow.com/questions/926656/entity-framework-with-nolock
テーブル&行のロックを行わないトランザクションを開けば良いようです。
この様にトランザクションレベルを変更したうえでその中のトランザクションで行えばエラーにはなりません。
(Entity Framework内部処理で自動的にトランザクションが実行されてしまうのを防ぐため)
ソースコード:
using (ExecuteSqlCommand execute = new ExecuteSqlCommand(IPAddress,
Port,
DBName,
UserId,
Password))
{
TransactionOptions transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = IsolationLevel.ReadUncommitted;
using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required,
transactionOptions))
{
Database.ExecuteSqlCommand("VACUUM (ANALYZE) public.AAAA;");
}
}最終的な完成したソース:
1.Postgresqlからユーザーテーブルのみを取得する
2.コネクションが残っていたら閉じる(isForcedフラグで強制的に閉じるかどうかを判断する)
3.トランザクションレベルをReadUncommittedに設定
4.全テーブルに対してVACUUM&ANALYZEを実行する
using (ExecuteSqlCommand execute = new ExecuteSqlCommand(IPAddress,
Port,
DBName,
UserId,
Password))
{
var tableList = (from c in PgClass
join n in PgNamespace on new
{
a = c.Relnamespace
} equals new
{
a = n.Oid
}
where !(new String[] { "pg_catalog", "pg_toast", "information_schema" }.Contains(n.Nspname))
&& c.Relkind == "r"
select new
{
tableName = n.Nspname + "." + c.Relname,
}).ToList();
if (isForced && Database.Connection.State == System.Data.ConnectionState.Open)
{
Database.Connection.Close();
}
TransactionOptions transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = IsolationLevel.ReadUncommitted;
using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required,
transactionOptions))
{
foreach (var table in tableList)
{
Database.ExecuteSqlCommand("VACUUM (ANALYZE) " + table.tableName + ";");
}
}
}検索用:Entity Framework Postgresql VACUUM Tranzaction Unlock バキューム ヴァキューム エラー VACUUM cannot run inside a transaction block
コメント
コメントを投稿