アクティブレコードでのトランザクション

昨日はSQLでのトランザクションについて書いたので、

今日はアクティブレコードでのトランザクションについて調べてみました!

 

 

書き方

 以下のように書くことができます。

① モデル.transaction do
② DBに変更を加える(updateやdeleteなど)

③ end

④ 上手くいった場合の処理

⑤  rescue => e

⑥  失敗した場合の処理

例外が時発生した場合にROLLBACKが発生するので、

モデル.transaction do ~ endの中の処理は例外を発生させるように書かないといけないようです。

(saveじゃなくてsave!とかく)

 

 

感想その他

アクティブレコードでのトランザクションは例外処理とセットになっているため、

モデル.transaction do ~ endの中の処理で例外を発生させるように書くことを気をつけなくてはと思いました。

 

 

 

 

トランザクション

トランザクションが何かということは書籍や記事を読んで知っていたのですが、先日初めて業務で使う機会があったのでメモしておこうと思います!

 

 

 トランザクションとは

一連のまとまった処理のことです。

処理の途中までしか実行されなかったらまずい処理などで使われます。

 

 

やり方

 以下のように、START TRANSACTION; ~~ COMMIT; でまとめたい処理を括って実行します。

① START TRANSACTION;
② DBに変更を加える(UPDATEやDELETEやCREATEなど)

③ 上手くできたか確認(SELECT実行したりして大丈夫であればCOMMIT、失敗していたらROLLBACKして①②の処理をやり直す)

④ COMMIT
;

 

 

① START TRANSACTION;

② UPDATE `reviews` SET `rate` = '1' WHERE `rate` = 0;

③ SESELECT *
   FROM 
`reviews`
   WHERE 
`rate` = 0;

④ COMMIT;

 

 

感想その他 

手を動かす前に本や記事で概要を知っておくのは大事だなと感じました。

 

 

 

HTMLで入れ子のリスト

 

マークダウンでよくあるような入れ子のリストをHTMLで作りたかったのですが、以下のやり方では上手くいきませんでした。

 

<ul>
  <li>リスト</li>
  <ul>
    <li>入れ子リスト</li>
    <li>入れ子リスト</li>
  </ul>
</ul>

 

 

 

調べてみたところ、以下のように親となるリストの閉じタグを入れ子リストの後に書かなくてはいけないようでした。

<ul>
  <li>リスト
  <ul>
    <li>入れ子リスト</li>
    <li>入れ子リスト</li>
  </ul>
  </li>
</ul>

 

 

 

感想その他

マークダウン便利だなあと感じました。

 

 

サブクエリとJOIN

サブクエリとJOINどちらでもデータ取得できることあるよな、比べてみよう、と思い比較してみました。

 

 

以下はどちらもeventsテーブルのidが1であるものと関連するpetsレコードを取得しています。

 

 JOIN

select * from pets join events on pets.name=events.name where events.id=1;

 結果

1 Whistler Gwen bird f 1989-08-30 NULL 2019-11-04 09:26:17 2019-11-04 09:26:17 1 Whistler 1999-11-09 Went hiking. 2019-11-09 13:23:43 2019-11-09 13:25:38

 

サブクエリ

select * from pets where name in(select name from events where id=1);

 結果

1 Whistler Gwen bird f 1989-08-30 NULL 2019-11-04 09:26:17 2019-11-04 09:26:17 1 Whistler 1999-11-09 Went hiking. 2019-11-09 13:23:43 2019-11-09 13:25:38

 

 

感想その他

JOINはテーブル同士くっつけているので、SELECT *とすればどちらのテーブルのカラムの値も返ってきますね。

一方サブクエリは最初にSELECT *した方のテーブルのデータのみ返ってきます。(当たり前かもですが)

 

こう比較してみるとJOINの方が応用効くし便利そうですね。

JOINしてGROUP BYでまとめてHAVINGで絞ってCOUNTしたりするのはサブクエリだと大変そうですし。。。サブクエリ側で予めデータ絞っておけばできるのかな。。。?

 

 

 

AS句

SQLを調べていると度々出てくるAS句について、なんとなくの理解だったので今回調べることにしました。

 

AS句とは

カラムに対して別の名前をつけることができる句です。

元々テーブルにあるカラム対しても、計算結果を表すカラムに対しても名前を付けることができます。

 

 

以下はreviewsテーブルのrateカラムに対してstarという別名をつけています。

SELECT rate AS  star FROM reviews WHERE product_id = 1;

 

以下の例はfirst_nameカラムとlast_nameカラムを結合したものをfullnameという別名をつけて取得しています。

 SELECT CONCAT(first_name, last_name) AS fullname FROM events;

 

AS句は略しても良いようですが、複数カラムをSELECTしているのと見間違うため、書く方が良いようです。

 

 

感想その他

AS句を知ってはいましたが、略せる事など知らなかったので調べてよかったです。

 

 

サブクエリ

以前から気になっていたサブクエリについて調べました〜

 

サブクエリとは

SELECT文の引数にまたSELECT文が渡されるようなクエリのことです。

 

 

SELECT * FROM events WHERE id in (1,3,5,7);

このようにin句で絞り込むSELECT文があるとします。

このidの配列を取得するためのSELECT文を直接引数として渡してしまうのがサブクエリです。以下はサブクエリ化したものです。

SELECT * FROM events WHERE id in (SELECT * FROM users WHERE name = Hayashi));

 

WHEREの引数だけでなく、以下のようにFROMの引数にサブクエリを取ることもできます。

SELECT count(*) FROM  (SELECT rate FROM reviews WHERE rate = 1);

 

サブクエリは一元配列を返すクエリにする必要があります。

 

 

 

感想その他

JOINでもサブクエリでも取得できる場合がありますが、サブクエリの方が親しみを感じます…

 

cloud watchからログを検索する

cloud watchの存在ははなんとなく知っておりましたがあまり触れたことがありませんでした。

 

本日cloud watchからログを検索する作業をしたのでその手順をメモしておく&cloud watchが何なのか調べることにしました。

 

cloud watchとは

awsが提供してくれている、アプリの管理&監視サービスです。

異常な状態を検知したらアラート投げてくれたり、インスタンスの起動停止も制御してくれるようです。

ログも管理してくれます。

 

 

cloud watchからログを検索する

1. awsのコンソールからcloud watchを選択

2. サイドバーからログを選択

3. アプリを選択

4. 確認したい日付のログを選択

5. 検索フィルタに探したいエラー文などのキーワードを""で囲って検索

 

 

これでみたいログが絞れます!

ここから更に詳しいログを見たいときは時刻等で検索し直せば、エラー前後のログも見れます!

 

 

感想その他

細かい調査が必要な場合はローカルへログファイルを落としてきた方が確認しやすいようですが、エラー原因のあたりをある程度つけるためならcloud watchが楽で便利だと思いました!!